package tankbb;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.Random;

public class Tank {

	public static final int TANK_STEP_PLUS = 10;
	public static final int TANK_STEP_MINUS = -10;
	public static final int TANK_WIDTH = 50;
	public static final int TANK_HEIGH = 50;
	public static final int BARREL_LENGTH = 50;
	
	private TankClient tc;
	public boolean good;
	private boolean live;
	
	public static int index_m;
	public static int index_t;
	int x, y, x2, y2;

	boolean up_flg = false;
	boolean down_flg = false;
	boolean left_flg = false;
	boolean right_flg = false;
	TankClient.Dir barrel_dir = TankClient.Dir.R;
	
	public Tank(int x, int y, TankClient tc, boolean g) {
		this.x = x;
		this.y = y;
		this.tc = tc;
		this.good = g;
		this.live = true;
		this.barrel_dir = TankClient.Dir.randomDir();
		
		turn(this.barrel_dir);
		
		if(g == false){
			new Thread(new TankPaint()).start();
		}
	}
	
	public boolean isLive(){
		return this.live;
	}
	
	public Rectangle getRec(){
		return new Rectangle(x, y, Tank.TANK_WIDTH, Tank.TANK_HEIGH);
	}
	
	public void keyPressed(KeyEvent e){
		switch(e.getKeyCode()){
		case KeyEvent.VK_W:
			up_flg = true;
			if(left_flg == true){
				this.barrel_dir = TankClient.Dir.LU;
				this.move(TANK_STEP_MINUS, TANK_STEP_MINUS);
			}else if(right_flg == true){
				this.barrel_dir = TankClient.Dir.UR;
				this.move(TANK_STEP_PLUS, TANK_STEP_MINUS);
			}else{
				this.barrel_dir = TankClient.Dir.U;
				this.move(0, TANK_STEP_MINUS);
			}
			this.turn(barrel_dir);
			break;
		
		case KeyEvent.VK_S:
			down_flg = true;
			if(left_flg == true){
				this.barrel_dir = TankClient.Dir.LD;
				this.move(TANK_STEP_MINUS, TANK_STEP_PLUS);
			}else if(right_flg == true){
				this.barrel_dir = TankClient.Dir.DR;
				this.move(TANK_STEP_PLUS, TANK_STEP_PLUS);
			}else{
				this.barrel_dir = TankClient.Dir.D;
				this.move(0, TANK_STEP_PLUS);
			}
			this.turn(barrel_dir);
			break;
		
		case KeyEvent.VK_A:
			left_flg = true;
			if(up_flg == true){
				this.barrel_dir = TankClient.Dir.LU;
				this.move(TANK_STEP_MINUS, TANK_STEP_MINUS);
			}else if(down_flg == true){
				this.barrel_dir = TankClient.Dir.LD;
				this.move(TANK_STEP_MINUS, TANK_STEP_PLUS);
			}else{
				this.barrel_dir = TankClient.Dir.L;
				this.move(TANK_STEP_MINUS, 0);
			}
			this.turn(barrel_dir);
			break;
		
		case KeyEvent.VK_D:
			right_flg = true;
			if(up_flg == true){
				this.barrel_dir = TankClient.Dir.UR;
				this.move(TANK_STEP_PLUS, TANK_STEP_MINUS);
			}else if(down_flg == true){
				this.barrel_dir = TankClient.Dir.DR;
				this.move(TANK_STEP_PLUS, TANK_STEP_PLUS);
			}else{
				this.barrel_dir = TankClient.Dir.R;
				this.move(TANK_STEP_PLUS, 0);
			}
			this.turn(barrel_dir);
			break;
		
		case KeyEvent.VK_J:
			if(!this.isLive()){break;};
			tc.arr_m.add(index_m++, new Missile(x2, y2, this.barrel_dir, this.tc, true));
			//TankClient.arr_m.add(new Missile(x2, y2, this.barrel_dir));
			break;
		case KeyEvent.VK_H:
			this.round();
			break;
		case KeyEvent.VK_F3:
			for(int i=0; i <3; i++){
				int random_x = (int)(TankClient.WIN_WIDTH*Math.random()); 
				int random_y = (int)(TankClient.WIN_HEIGH*Math.random());
				
				if((random_x + Tank.TANK_WIDTH) > TankClient.WIN_WIDTH){random_x -= 200;}
				if((random_y + Tank.TANK_HEIGH) > TankClient.WIN_HEIGH){random_y -= 200;}
				if((random_x - Tank.TANK_WIDTH) < 0){random_x += 200;}
				if((random_y - Tank.TANK_HEIGH) < 0){random_y += 200;}
				
				tc.arr_t.add(index_t++, new Tank(random_x, random_y, tc, false));
			}
			break;
		}
	}
	
	public void keyReleased(KeyEvent e){
		switch(e.getKeyCode()){
		case KeyEvent.VK_W:
			up_flg = false;
			break;
		case KeyEvent.VK_S:
			down_flg = false;
			break;
		case KeyEvent.VK_A:
			left_flg = false;
			break;
		case KeyEvent.VK_D:
			right_flg = false;
			break;
		}
	}
	
	public void round(){
		TankClient.Dir d = TankClient.Dir.R;
		switch(barrel_dir){
		case U:
			d = TankClient.Dir.LU;
			break;
		case UR:
			d = TankClient.Dir.U;
			break;
		case R:
			d = TankClient.Dir.UR;
			break;
		case DR:
			d = TankClient.Dir.R;
			break;
		case D:
			d = TankClient.Dir.DR;
			break;
		case LD:
			d = TankClient.Dir.D;
			break;
		case L:
			d = TankClient.Dir.LD;
			break;
		case LU:
			d = TankClient.Dir.L;
			break;
		}
		barrel_dir = d;
		turn(d);
	}
	
	public void turn(TankClient.Dir d){
		switch(d){
		case U:
			x2 = x+TANK_WIDTH/2;
			y2 = y+TANK_HEIGH/2 - BARREL_LENGTH;
			break;
		case UR:
			x2 = x+TANK_WIDTH/2 + BARREL_LENGTH;
			y2 = y+TANK_HEIGH/2 - BARREL_LENGTH;
			break;
		case R:
			x2 = x+TANK_WIDTH/2 + BARREL_LENGTH;
			y2 = y+TANK_HEIGH/2;
			break;
		case DR:
			x2 = x+TANK_WIDTH/2 + BARREL_LENGTH;
			y2 = y+TANK_HEIGH/2 + BARREL_LENGTH;
			break;
		case D:
			x2 = x+TANK_WIDTH/2;
			y2 = y+TANK_HEIGH/2 + BARREL_LENGTH;
			break;
		case LD:
			x2 = x+TANK_WIDTH/2 - BARREL_LENGTH;
			y2 = y+TANK_HEIGH/2 + BARREL_LENGTH;
			break;
		case L:
			x2 = x+TANK_WIDTH/2 - BARREL_LENGTH;
			y2 = y+TANK_HEIGH/2;
			break;
		case LU:
			x2 = x+TANK_WIDTH/2 - BARREL_LENGTH;
			y2 = y+TANK_HEIGH/2 - BARREL_LENGTH;
			break;
		}
	}
	
	public void setDead(){
		this.live = false;
	}
	
	public void draw(Graphics g){
		Color c = g.getColor();
		if(this.good){
			g.setColor(Color.BLUE);
		}else{
			g.setColor(Color.GREEN);
		}
		g.fillRoundRect(x, y, TANK_WIDTH, TANK_HEIGH, 20, 20);
		g.setColor(Color.BLACK);
		g.drawLine(x+TANK_WIDTH/2, y+TANK_HEIGH/2, x2, y2);
		g.setColor(c);
	}
	
	public void move(int i, int j){
		this.x += i;
		this.y += j;
		
		if(x > TankClient.WIN_WIDTH - Tank.TANK_WIDTH){
			x = TankClient.WIN_WIDTH - Tank.TANK_WIDTH;
		}
		
		if(x < 0){
			x = 0;
		}
		
		if(y > TankClient.WIN_HEIGH - Tank.TANK_HEIGH){
			y = TankClient.WIN_HEIGH - Tank.TANK_HEIGH;
		}
		
		if(y < 25){
			y = 25;
		}
	}
	
	public boolean chkXY(){
		boolean rtn = true;
		if(	(x > TankClient.WIN_WIDTH - Tank.TANK_WIDTH - 5)||
			(x < 30)||
			(y > TankClient.WIN_HEIGH - Tank.TANK_HEIGH - 5)||
			(y < 30)
		){rtn = false;}
		return rtn;
	}
	
	public void moveStep(TankClient.Dir dir){
		
		turn(dir);
		switch(dir){
		case U:
			move(0, TANK_STEP_MINUS);
			break;
		case UR:
			move(TANK_STEP_PLUS, TANK_STEP_MINUS);
			break;
		case R:
			move(TANK_STEP_PLUS, 0);
			break;
		case DR:
			move(TANK_STEP_PLUS, TANK_STEP_PLUS);
			break;
		case D:
			move(0, TANK_STEP_PLUS);
			break;
		case LD:
			move(TANK_STEP_MINUS, TANK_STEP_PLUS);
			break;
		case L:
			move(TANK_STEP_MINUS, 0);
			break;
		case LU:
			move(TANK_STEP_MINUS, TANK_STEP_MINUS);
			break;
		}
	}
	
	private class TankPaint implements Runnable{

		public void run() {
			Random r = null;
			int step;
			TankClient.Dir dir = null;
			int fireStep;
			int cnt = 0;
			
			while(live){
				r = new Random();
				step = r.nextInt(TankClient.WIN_WIDTH/(TANK_STEP_PLUS*2));
				dir = TankClient.Dir.randomDir();
				fireStep = r.nextInt(10);
				
				for(int i=0; i < step; i++){
					moveStep(dir);
					if(!chkXY()){
						dir = TankClient.Dir.randomDir();
					}
					try {
						Thread.sleep(300);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					cnt++;
					
					if(cnt == fireStep){
						tc.arr_m.add(index_m++, new Missile(x2, y2, dir, tc, false));
					}
				}
				cnt = 0;
			}
		}
	}
}
